package com.spring.aicloud.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import jakarta.annotation.Resource;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import com.spring.aicloud.entity.Answer;
import com.spring.aicloud.entity.enums.AiModelEnum;
import com.spring.aicloud.entity.enums.AiTypeEnum;
import com.spring.aicloud.service.IAnswerService;
import com.spring.aicloud.util.AppVariable;
import com.spring.aicloud.util.ResponseEntity;
import com.spring.aicloud.util.SecurityUtil;
import org.springframework.ai.ollama.OllamaChatClient;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * 调用本地 OpenAI 大模型
 */
@RestController
@RequestMapping("/chatgpt")
public class ChatGptController {

    @Resource
    private IAnswerService answerService;
    @Resource
    private RedissonClient redissonClient;
    @Resource
    private OllamaChatClient ollamaChatClient;
    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 调用 Open AI 聊天接口
     *
     * @param question
     * @return
     */
    @PostMapping("/chat")
    public ResponseEntity chat(String question) {
        if (!StringUtils.hasLength(question)) {
            return ResponseEntity.fail("请先输入内容！");
        }
        Long uid = SecurityUtil.getCurrentUser().getUid();
        String lockKey = AppVariable.getModelLockKey(uid, AiModelEnum.OPENAI.getValue(), AiTypeEnum.CHAT.getValue());
        String result = "";
        boolean isSave = false;
        RLock rLock = redissonClient.getLock(lockKey);
        try {
            boolean isLock = rLock.tryLock(30, TimeUnit.SECONDS);
            if (!isLock) {
                return ResponseEntity.fail("请勿频繁调用接口！");
            }
            result = ollamaChatClient.call(question);
            Answer answer = new Answer();
            answer.setTitle(question);
            answer.setContent(result);
            answer.setModel(AiModelEnum.OPENAI.getValue());
            answer.setType(AiTypeEnum.CHAT.getValue());
            answer.setUid(uid);
            isSave = answerService.save(answer); // 保存回答到数据库
            if (isSave) {
                // 如果保存成功，更新缓存
                int type = AiTypeEnum.CHAT.getValue();
                int model = AiModelEnum.OPENAI.getValue();
                String cacheKey = AppVariable.getListCacheKey(uid, model, type);
                List<Answer> cachedList = new ArrayList<>();
                Object cachedData = redisTemplate.opsForValue().get(cacheKey);
                if (cachedData != null) {
                    cachedList = (List<Answer>) cachedData;
                }
                cachedList.add(0,answer); // 将新回答添加到缓存列表中  // 0 表示在列表开头插入
                redisTemplate.opsForValue().set(cacheKey, cachedList, 1, TimeUnit.DAYS); // 更新缓存
            }
        } catch (Exception e) {
            e.printStackTrace(); // 记录异常信息
            return ResponseEntity.fail("系统繁忙，请稍后再试！");
        } finally {
            rLock.unlock();
        }
        return ResponseEntity.succ(result);
    }

    @PostMapping("/getchatlist")
    public ResponseEntity getChatList() {
        Long uid = SecurityUtil.getCurrentUser().getUid();
        int type = AiTypeEnum.CHAT.getValue();
        int model = AiModelEnum.OPENAI.getValue();
        String cacheKey = AppVariable.getListCacheKey(uid, model, type);
        Object list = redisTemplate.opsForValue().get(cacheKey);
        if (list == null) { // 缓存不存在
            QueryWrapper<Answer> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("uid", uid);
            queryWrapper.eq("type", type);
            queryWrapper.eq("model", model);
            queryWrapper.orderByDesc("aid");
            List<Answer> dataList = answerService.list(queryWrapper);
            // 存储到缓存中
            redisTemplate.opsForValue().set(cacheKey, dataList, 1, TimeUnit.DAYS);
            return ResponseEntity.succ(dataList);
        } else {
            return ResponseEntity.succ(list);
        }
    }
}
